package service

import (
	"fmt"
	"ginchat/models"
	"ginchat/utils"
	"log"
	"math/rand"
	"net/http"
	"strconv"
	"time"

	"github.com/asaskevich/govalidator"
	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
)

// GetUserList
// @Summary 所有用户
// @Tags 用户模块
// @Success 200 {string} json{"code","message"}
// @Router /user/getUserList [get]
func GetUserList(c *gin.Context) {
	data := make([]*models.UserBasic, 10)
	fmt.Println(data)
	data = models.GetUserList()

	c.JSON(200, gin.H{
		"code":    0, //  0成功   -1失败
		"message": "用户名已注册！",
		"data":    data,
	})
}

// CreateUser
// @Summary 新增用户
// @Tags 用户模块
// @param name query string false "用户名"
// @param password query string false "密码"
// @param repassword query string false "确认密码"
// @param phone query string false "phone"
// @param email query string false "email"
// @Success 200 {string} json{"code","message"}
// @Router /user/createUser [get]
func CreateUser(c *gin.Context) {
	user := models.UserBasic{}
	user.Name = c.Query("name")
	user.Phone = c.Query("phone")
	user.Email = c.Query("email")

	//确认密码校验
	password := c.Query("password")
	repassword := c.Query("repassword")
	if password != repassword {
		c.JSON(200, gin.H{
			"code":    -1, //  0成功   -1失败
			"message": "两次密码不一致！",
			"data":    user,
		})
		//密码不一致直接return
		return
	}

	//电话或者邮箱格式校验
	_, err := govalidator.ValidateStruct(user)
	if err != nil {
		fmt.Println(err)
		c.JSON(200, gin.H{
			"code":    -1, //  0成功   -1失败
			"message": "电话或者邮箱格式不正确",
			"data":    user,
		})
		return
	}

	//用户名注册重复校验
	checkuser1 := models.FindUserByName(user.Name)
	if checkuser1.Name != "" {
		c.JSON(200, gin.H{
			"code":    -1, //  0成功   -1失败
			"message": "用户名已注册",
			"data":    user,
		})
		return
	}

	//电话注册重复校验
	checkuser2 := models.FindUserByPhone(user.Phone)
	if checkuser2.Phone != "" {
		c.JSON(200, gin.H{
			"code":    -1, //  0成功   -1失败
			"message": "电话已注册",
			"data":    user,
		})
		return
	}

	//邮箱注册重复校验
	checkuser3 := models.FindUserByEmail(user.Email)
	if checkuser3.Email != "" {
		c.JSON(200, gin.H{
			"code":    -1, //  0成功   -1失败
			"message": "邮箱已注册",
			"data":    user,
		})
		return
	}

	//前面几个return都没有return成功的话就证明满足所有规则

	salt := fmt.Sprintf("%06d", rand.Int31())
	user.Salt = salt
	user.PassWord = utils.MakePassword(password, salt)
	fmt.Println(user.PassWord)
	models.CreateUser(user)
	c.JSON(200, gin.H{
		"message": "新增用户成功！",
	})
}

// DeleteUser
// @Summary 删除用户
// @Tags 用户模块
// @param id query string false "id"
// @Success 200 {string} json{"code","message"}
// @Router /user/deleteUser [get]
func DeleteUser(c *gin.Context) {
	user := models.UserBasic{}
	//go中不允许直接转换 go是静态类型的语言，类型必须明确匹配 要使用strconv
	id, err := strconv.ParseUint(c.Query("ID"), 10, 32) // 10 是基数，32 是位数
	if err != nil {
		// 处理转换错误
		c.JSON(200, gin.H{
			"error": "无效的 ID",
		})
		return
	}
	user.ID = uint(id)
	// user.ID = strconv.Atoi(c.Query("ID"))
	models.DeleteUser(user)
	c.JSON(200, gin.H{
		"message": "删除用户成功！",
	})
}

// UpdateUser
// @Summary 修改用户
// @Tags 用户模块
// @param id formData string false "id"
// @param name formData string false "name"
// @param password formData string false "password"
// @param phone formData string false "phone"
// @param email formData string false "email"
// @Success 200 {string} json{"code","message"}
// @Router /user/updateUser [post]
func UpdateUser(c *gin.Context) {
	user := models.UserBasic{}
	id, err := strconv.Atoi(c.PostForm("id"))
	if err != nil {
		c.JSON(200, gin.H{
			"error": "无效的 ID",
		})
		return
	}
	user.ID = uint(id)
	user.Name = c.PostForm("name")
	user.PassWord = c.PostForm("password")
	user.Phone = c.PostForm("phone")
	user.Email = c.PostForm("email")
	fmt.Println("update :", user)
	// user.ID = strconv.Atoi(c.Query("ID"))

	_, err1 := govalidator.ValidateStruct(user)
	if err1 != nil {
		fmt.Println(err1)
		c.JSON(200, gin.H{
			"code":    -1, //  0成功   -1失败
			"message": "修改参数不匹配！",
			"data":    user,
		})
	} else {
		models.UpdateUser(user)
		c.JSON(200, gin.H{
			"code":    0, //  0成功   -1失败
			"message": "修改用户成功！",
			"data":    user,
		})
	}
}

// GetUser
// @Summary 登录
// @Tags 用户模块
// @param name formData string false "用户名"
// @param password formData string false "密码"
// @Success 200 {string} json{"code","message"}
// @Router /user/findUserByNameAndPwd [post]
func FindUserByNameAndPwd(c *gin.Context) {
	//这里待会用一下get会怎么样呢
	name := c.PostForm("name")
	password := c.PostForm("password")

	user := models.UserBasic{}
	user = models.FindUserByName(name)
	fmt.Println(user.Name)

	if user.Name == "" {
		c.JSON(200, gin.H{
			"code":    -1, //  0成功   -1失败
			"message": "用户名不存在",
			"data":    user,
		})
		return
	}

	flag := utils.ValidPassword(password, user.Salt, user.PassWord)
	if !flag {
		c.JSON(200, gin.H{
			"code":    -1, //  0成功   -1失败
			"message": "用户名或密码不正确",
			"data":    user,
		})
		return
	}
	//登陆成功
	pwd := utils.MakePassword(password, user.Salt)
	user = models.FindUserByNameAndPwd(name, pwd)
	c.JSON(200, gin.H{
		"message": "登陆成功",
		"data":    user,
	})
}

// 可以在这里写条件使得防止伪基站跨境访问
var upGrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		//只有使用了令牌才能实现我进行请求 但是这里好像没有写？？
		return true
	},
}

func SendMsg(c *gin.Context) {
	//建立持久性通信的通道
	ws, err := upGrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		fmt.Println(err)
		return
	}
	//匿名函数关闭流
	defer func(wsqw *websocket.Conn) {
		err = wsqw.Close()
		if err != nil {
			fmt.Println(err)
		}
	}(ws)
	MsgHandler(c, ws)
}
func MsgHandler(c *gin.Context, ws *websocket.Conn) {
	for {
		msg, err := utils.Subscribe(c, utils.PublishKey)
		if err != nil {
			fmt.Println(" MsgHandler 发送失败", err)
		}
		tm := time.Now().Format("2006-01-02 15:04:05")
		m := fmt.Sprintf("[ws][%s]:%s", tm, msg)
		err = ws.WriteMessage(1, []byte(m))
		if err != nil {
			log.Fatalln(err)
		}
	}
}
